// hdu4081
// 题意：给定n<<=1000>个城市点坐标以及每个城市人口。定义A为某一条魔法路
//       连接的两个城市人口和，定义B将所有城市联通，除了魔法路之外的边权
//       最小值。求最大化A/B。
//
// 题解：先求出最小生成树。然后枚举魔法边。如果该边在最小生成树上，那么
//       B的值就是最小生成树减去该边的边权。如果不在，那么肯定会产生一个
//       环，B的值就是最小生成树减去环最大的边权。而维护这个最大边权相当
//       于维护树上两点最大边，这个是可以有很多方法维护的，不过这道题数据
//       比较小，可以在prim的过程中用数组记录下来维护，这也是对应求次小生
//       成树的过程。
//
// 统计：156ms, 33min, 1wa
//
// run: $exec < input
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>

struct edge { int from, to; double cost; };

bool operator<(edge const & a, edge const & b)
{
	return a.cost > b.cost;
}

struct data { int x, y, p; };

int const maxn = 1010;
bool vis[maxn];
bool span_tree[maxn][maxn];
data da[maxn];
double map[maxn][maxn];
double max_edge[maxn][maxn];
int n;

double dis(int x1, int y1, int x2, int y2)
{
	return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}

void init()
{
	std::memset(vis, 0, sizeof(vis));
	std::memset(span_tree, 0, sizeof(span_tree));
	std::memset(max_edge, 0, sizeof(max_edge));
	for (int i = 1; i <= n; i++)
		for (int j = i + 1; j <= n; j++)
			map[i][j] = map[j][i] = dis(da[i].x, da[i].y, da[j].x, da[j].y);
}

int main()
{
	int T; std::scanf("%d", &T);
	while (T--) {
		std::scanf("%d", &n);
		for (int i = 1; i <= n; i++)
			std::scanf("%d %d %d", &da[i].x, &da[i].y, &da[i].p);
		init();
		std::priority_queue<edge> pq;
		vis[1] = true;
		for (int i = 2; i <= n; i++) {
			edge tmp;
			tmp.from = 1; tmp.to = i; tmp.cost = map[i][1];
			pq.push(tmp);
		}
		double span = 0;
		for (int i = 1; i < n; i++) {
			while (!pq.empty() && vis[pq.top().to]) pq.pop();
			if (pq.empty()) continue;
			edge now = pq.top(); pq.pop();
			span_tree[now.from][now.to] = span_tree[now.to][now.from] = true;
			span += now.cost;
			vis[now.to] = true;
			for (int j = 1; j <= n; j++) {
				if (j == now.to) continue;
				if (vis[j]) {
					max_edge[j][now.to] = max_edge[now.to][j] =
						std::max(max_edge[now.from][j], now.cost);
				} else {
					edge tmp;
					tmp.from = now.to; tmp.to = j; tmp.cost = map[now.to][j];
					pq.push(tmp);
				}
			}
		}

		double ans = 0;
		for (int i = 1; i <= n; i++)
			for (int j = i + 1; j <= n; j++) {
				double a = da[i].p + da[j].p;
				if (span_tree[i][j]) {
					ans = std::max(ans, a / (span - map[i][j]));
				} else {
					ans = std::max(ans, a / (span - max_edge[i][j]));
				}
			}
		std::printf("%.2lf\n", ans);
	}
}

